package co.fitstart.mobile.web.controller.order;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.BusinessException;
import com.demo2do.core.support.Result;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.wechat.web.interceptor.WechatJsConfig;

import co.fitstart.entity.order.Order;
import co.fitstart.entity.order.OrderInvestigateRecord;
import co.fitstart.entity.user.User;
import co.fitstart.entity.user.fit.Shape;
import co.fitstart.entity.user.fit.UserFit;
import co.fitstart.entity.user.investigation.FitInvestigation;
import co.fitstart.entity.user.investigation.HealthInvestigation;
import co.fitstart.entity.user.investigation.ParticipateInvestigation;
import co.fitstart.entity.user.investigation.ProfileInvestigation;
import co.fitstart.entity.user.profile.UserProfile;
import co.fitstart.mobile.handler.QrcodeHandler;
import co.fitstart.mobile.service.InvestigationService;
import co.fitstart.mobile.service.OrderService;
import co.fitstart.mobile.web.interceptor.MobileDetect;
import co.fitstart.mobile.web.interceptor.Router;
import co.fitstart.mobile.web.interceptor.WechatAuthority;
import co.fitstart.mobile.web.resolver.Secure;

@Controller
@RequestMapping("/orders/{orderId}/investigations")
public class OrderInvestigationController {
    
    private static final Logger logger = LoggerFactory.getLogger(OrderInvestigationController.class);
    
    @Autowired
    private OrderService orderService;
    
    @Autowired
    private InvestigationService investigationService;
    
    @Autowired
    private QrcodeHandler qrcodeHandler;
    
    /**
     * 
     * @param orderId
     * @return
     */
    @RequestMapping("")
    @Router
    @WechatAuthority(targetUrl = "/need-investigation")
    @MobileDetect
    @WechatJsConfig
    public ModelAndView index(@PathVariable("orderId") Long orderId) {
        
        ModelAndView modelAndView = new ModelAndView();
        
        Order order = orderService.load(Order.class, orderId);
        if(order == null) {
            modelAndView.setViewName("redirect:/orders/" + orderId + "/investigations/error");
            return modelAndView;
        }
        
        OrderInvestigateRecord orderInvestigateRecord = orderService.loadOrderInvestigateRecord(order);
        if(orderInvestigateRecord == null) {
            modelAndView.setViewName("redirect:/orders/" + orderId + "/investigations/error");
            return modelAndView;
        }
        
        if(orderInvestigateRecord.isFinish()) {
            modelAndView.setViewName("redirect:/orders/" + orderId + "/investigations/finish");
            return modelAndView;
        }
        
        // goto thirdpart investigation
        if(orderInvestigateRecord.gotoThirdPart()) {
            modelAndView.setViewName("redirect:" + orderInvestigateRecord.getThirdPart());
            return modelAndView;
        }
        
        // goto profile investigation
        if(orderInvestigateRecord.needProfileInvestigation()) {
            modelAndView.setViewName("redirect:/orders/" + orderId + "/investigations/profile");
            return modelAndView;
        }
        
        // goto fit investigation
        if(orderInvestigateRecord.needFitInvestigation()) {
            modelAndView.setViewName("redirect:/orders/" + orderId + "/investigations/fit");
            return modelAndView;
        }
        
        // goto health investigation
        if(orderInvestigateRecord.needHealthInvestigation()) {
            modelAndView.setViewName("redirect:/orders/" + orderId + "/investigations/health");
            return modelAndView;
        }
        
        // goto participate investigation
        if(orderInvestigateRecord.needParticipateInvestigation()) {
            modelAndView.setViewName("redirect:/orders/" + orderId + "/investigations/participate");
            return modelAndView;
        }
        
        return modelAndView;
    }
    
    /**
     * 
     * @param user
     * @param orderId
     * @return
     */
    @RequestMapping("/profile")
    @Router
    @WechatAuthority(targetUrl = "/need-investigation")
    @MobileDetect
    @WechatJsConfig
    public ModelAndView profile(@Secure User user,
                                @PathVariable("orderId") Long orderId) {
        ModelAndView modelAndView = new ModelAndView("order/investigation/profile-investigation");
        
        Order order = orderService.load(Order.class, orderId);
        modelAndView.addObject("order", order);
        
        modelAndView.addObject("user", user);
        
        UserProfile userProfile = user.getProfile() == null ? new UserProfile() : user.getProfile();
        modelAndView.addAllObjects(userProfile.describe());
        
        return modelAndView;
    }
    
    /**
     * 
     * @param user
     * @param orderId
     * @param mediaId
     * @param profileInvestigation
     * @return
     */
    @RequestMapping(value = "/profile", method = RequestMethod.PATCH)
    @Router
    @WechatAuthority(targetUrl = "/need-investigation")
    @MobileDetect
    public @ResponseBody String onEditProfile(@Secure User user,
                                              @PathVariable("orderId") Long orderId,
                                              @RequestParam(value = "mediaId", required = false) String mediaId,
                                              ProfileInvestigation profileInvestigation) {
        
        Result result = new Result();
        
        try {
            
            Result saveUserQrcodeResult = null;
            
            Order order = orderService.load(Order.class, orderId);
            OrderInvestigateRecord orderInvestigateRecord = orderService.loadOrderInvestigateRecord(order);
            
            // Step1: if mediaId is not empty & userProfile's qrcodePath is empty, save qrcode file
            if(StringUtils.isEmpty(mediaId) && !user.hasQrcode()) {   // empty both, throw new error
                
                throw new BusinessException("请上传二维码");
            
            }  else if (StringUtils.isEmpty(mediaId) && user.hasQrcode()) {
                user = qrcodeHandler.changeUserQrcode(user, profileInvestigation.getWechatCode());
                profileInvestigation.editQrcodePath(user.getWechat().getQrcode());
                orderInvestigateRecord.saveQrcodeSuccess();
            }
            else if(StringUtils.isNotEmpty(mediaId)) { // empty qrcodePath, but not empty mediaTd, save file
                
                saveUserQrcodeResult = qrcodeHandler.saveUserQrcode(profileInvestigation.getWechatCode(), mediaId);
                
                if (saveUserQrcodeResult.isValid()) {
                    profileInvestigation.editQrcodePath(saveUserQrcodeResult.getData().get("fileName").toString());
                    orderInvestigateRecord.saveQrcodeSuccess();
                } else {
                    orderInvestigateRecord.saveQrcodeFailure(saveUserQrcodeResult.getMessage());
                }
            }
            
            // edit investigateRecord
            if(orderInvestigateRecord.getProfileInvestigation() != null) {
                profileInvestigation = orderInvestigateRecord.getProfileInvestigation().edit(profileInvestigation);
            }
            
            if(saveUserQrcodeResult != null && !saveUserQrcodeResult.isValid()) {
                orderInvestigateRecord.saveQrcodeFailure(saveUserQrcodeResult.getMessage());
            }
            
            investigationService.editProfile(user, orderInvestigateRecord, profileInvestigation);
            
            result.success().message("编辑基本信息成功");
            
        } catch (Exception e) {
            logger.error("onEditProfile() error", e);
            result.fail().message("编辑基本信息失败");
        }
        
        return JsonUtils.toJsonString(result);
    }

    /**
     * 
     * @param user
     * @param orderId
     * @return
     */
    @RequestMapping("/fit")
    @Router
    @WechatAuthority(targetUrl = "/need-investigation")
    @MobileDetect
    @WechatJsConfig
    public ModelAndView fit(@Secure User user,
                            @PathVariable("orderId") Long orderId) {
        ModelAndView modelAndView = new ModelAndView("order/investigation/fit-investigation");
        
        Order order = orderService.load(Order.class, orderId);
        modelAndView.addObject("order", order);
        
        UserFit userFit = user.getUserFit() == null ? new UserFit() : user.getUserFit();
        modelAndView.addObject("userFit", userFit);
        
        return modelAndView;
    }

    /**
     * 
     * @param user
     * @param shapeId
     * @param orderId
     * @param fitInvestigation
     * @return
     */
    @RequestMapping(value = "/fit", method = RequestMethod.PATCH)
    @Router
    @WechatAuthority
    @MobileDetect
    public @ResponseBody String onEditFit(@Secure User user,
                                          @PathVariable("orderId") Long orderId,
                                          @RequestParam(value = "shapeId") Long shapeId,
                                          FitInvestigation fitInvestigation) {
        
        Result result = new Result();
        
        try {
            
            Shape shape = investigationService.loadShape(shapeId);
            
            Order order = orderService.load(Order.class, orderId);
            OrderInvestigateRecord orderInvestigateRecord = orderService.loadOrderInvestigateRecord(order);
            
            if(orderInvestigateRecord.getFitInvestigation() != null) {
                fitInvestigation = orderInvestigateRecord.getFitInvestigation().edit(fitInvestigation);
            }
            
            investigationService.editFit(user, orderInvestigateRecord, fitInvestigation, shape);
            
            result.success().message("编辑身体数据成功");
            
        } catch (Exception e) {
            
            logger.error("onEditFir() error", e);
            result.fail().message("编辑身体数据失败");
        }
        
        return JsonUtils.toJsonString(result);
    }

    /**
     * 
     * @param user
     * @param orderId
     * @return
     */
    @RequestMapping("/health")
    @Router
    @WechatAuthority(targetUrl = "/need-investigation")
    @MobileDetect
    @WechatJsConfig
    public ModelAndView health(@Secure User user,
                               @PathVariable("orderId") Long orderId) {
        ModelAndView modelAndView = new ModelAndView("order/investigation/health-investigation");
        
        HealthInvestigation healthInvestigation = investigationService.loadLastHealth(user);
        modelAndView.addObject("healthInvestigation", healthInvestigation);
        
        Order order = orderService.load(Order.class, orderId);
        modelAndView.addObject("order", order);
        
        return modelAndView;
    }

    /**
     * 
     * @param user
     * @param orderId
     * @param healthInvestigation
     * @return
     */
    @RequestMapping(value = "/health", method = RequestMethod.PATCH)
    @Router
    @WechatAuthority
    @MobileDetect
    public @ResponseBody String onEditHealth(@Secure User user,
                                             @PathVariable("orderId") Long orderId,
                                             HealthInvestigation healthInvestigation) {
        
        Result result = new Result();
        
        try {
            
            Order order = orderService.load(Order.class, orderId);
            OrderInvestigateRecord orderInvestigateRecord = orderService.loadOrderInvestigateRecord(order);
            
            if(orderInvestigateRecord.getHealthInvestigation() != null) {
                healthInvestigation = orderInvestigateRecord.getHealthInvestigation().edit(healthInvestigation);
            }
            
            investigationService.editHealth(user, orderInvestigateRecord, healthInvestigation);
            
            result.success().message("编辑健康调查成功");
            
        } catch (Exception e) {
            
            logger.error("onEditHealth() error", e);
            
            result.fail().message("编辑健康调差失败");
        }
        
        return JsonUtils.toJsonString(result);
    }

    /**
     * 
     * @param user
     * @param orderId
     * @return
     */
    @RequestMapping("/participate")
    @Router
    @WechatAuthority(targetUrl = "/need-investigation")
    @MobileDetect
    @WechatJsConfig
    public ModelAndView participate(@Secure User user,
                                    @PathVariable("orderId") Long orderId) {
        
        ModelAndView modelAndView = new ModelAndView("order/investigation/participate-investigation");
        
        ParticipateInvestigation participateInvestigation = investigationService.loadLastParticipate(user);
        modelAndView.addObject("participateInvestigation", participateInvestigation);
        
        Order order = orderService.load(Order.class, orderId);
        modelAndView.addObject("order", order);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param user
     * @param orderId
     * @param participateInvestigation
     * @return
     */
    @RequestMapping(value = "/participate", method = RequestMethod.PATCH)
    @Router
    @WechatAuthority
    @MobileDetect
    public @ResponseBody String onEditParticipate(@Secure User user,
                                                  @PathVariable("orderId") Long orderId,
                                                  ParticipateInvestigation participateInvestigation) {
        
        Result result = new Result();
        
        try {
            
            if(user == null) {
                result.fail().message("编辑其他调查失败，当前用户不存在");
                return JsonUtils.toJsonString(result);
            }
            
            Order order = orderService.load(Order.class, orderId);
            OrderInvestigateRecord orderInvestigateRecord = orderService.loadOrderInvestigateRecord(order);
            
            if(orderInvestigateRecord.getParticipateInvestigation() != null) {
                participateInvestigation = orderInvestigateRecord.getParticipateInvestigation().edit(participateInvestigation);
            }
            
            investigationService.editParticipate(user, orderInvestigateRecord,  participateInvestigation);
            
            result.success().message("编辑其他调查成功");
            
        } catch (Exception e) {
            
            logger.error("onEditParticipate() error", e);
            
            result.fail().message("编辑其他调查失败");
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * 
     * @return
     */
    @RequestMapping(value = "/error")
    public String error() {
        return "order/investigation/error";
    }
    
    /**
     * 
     * @return
     */
    @RequestMapping(value = "/finish")
    public ModelAndView finish() {
        ModelAndView modelAndView = new ModelAndView("order/investigation/finish");
        
        modelAndView.addObject("orderType", "online");
        
        return modelAndView;
    }
}
